<?php

/**
 * 安心站长axzz.cn，一个追求技术创造者。让网站、小程序、APP牛起来……
 *
 * cighsen02 3651872575
 *
 * Create at: 2024.05.05
 * Update at: 2025.08.26
*/

namespace Twoir\Service\Info;

use Config;
use Exception;
use Twoir\Service\BaseInfo;
use Twoir\System\Support\ParamTrait;

/**
 * 信息详情
*/
class Detail extends BaseInfo
{
    use ParamTrait;

    const ALLOW = ['classid', 'id', 'pathid', 'tablename', 'filename'];
    // 当次拉取缓存列表
    protected $info;
    /**
     * 获取详情
     *
     * @param array $add
     * @return array
     *
     * @throws Exception
    */
    public function get(array $add): array
    {
        // 过滤无关参数
        $add = $this->paramFilter($add);

        if (empty($add)) throw new Exception("参数错误!", 9200);

        if (!isset($add['classid']) || empty($add['classid'] = (int)$add['classid'])) {

            if (!isset($add['tablename']) || empty($add['tablename'])) {

                throw new Exception("classid或tablename必要参数", 9200);
            }
        }

        if (!isset($add['id']) || empty($add['id'] = (int)$add['id'])) throw new Exception("id必要参数", 9200);
        // 键名采用小驼峰命名
        $modelName  = camel_case($this->modelName());
        // 定义获取的字段
        $field      = Config::twoir('api.' . $modelName . '.page') ?? ['*'];
        $result     = $this->getOne(['id' => $add['id']], $field);

        return $this->format($result);
    }

    /**
     * 点击统计
     *
     * @param array $add
     * @return array
     *
     * @throws Exception
     */
    public function onClick(array $add): array
    {
        // 过滤无关参数
        $add = $this->paramFilter($add);

        if (empty($add)) throw new Exception('参数错误!', 9200);

        if (!isset($add['classid']) || empty($add['classid'] = (int)$add['classid'])) {

            if (!isset($add['tablename']) || empty($add['tablename'])) {

                throw new Exception('classid或tablename必要参数', 9200);
            }
        }

        if (!isset($add['id']) || empty($add['id'] = (int)$add['id'])) throw new Exception("id必要参数", 9200);

        return $this->click($add);
    }

    /**
     * 执行点击
     * 
     * @param array $add
     * @return array
     * 
     * @throws Exception
     */
    private function click(array $add)
    {
        global $public_r, $emod_pubr, $class_r;

        if (!$this->checkCookie('ecookieinforecord', $add['classid'] . '-' . $add['id'])) return [];

        if(empty($this->tablename) || InfoIsInTable(strtolower($this->tablename))) return [];
        // 获取字段，表没有时自动过虑，多写不影响
        if (empty($r = $this->getOne(['id' => $add['id']], ['id','eotime','eoday']))) throw new Exception('信息不存在', 9200);

        // onclicktype: 0实时统计,1文本缓存,2不统计
        if(0 === (int)$public_r['onclicktype'])	{

            // 浏览年月日统计 前缀eo为浏览 ed为下载
            $tid 	= $class_r[$add['classid']]['tid'];
            $update = ['onclick' => 'onclick + 1'];
            if(str_contains($emod_pubr['tbidseo'], ',' . $tid . ',')) {

                if (isset($r['eotime'])) {
                    $nowtime 	= time();
                    $date		= date('Y-m-d', $nowtime);
                    $year		= date('Y', $nowtime);
                    $month		= date('n', $nowtime);
                    $week		= date('W', $nowtime);
                    $day		= date('j', $nowtime);
                    $halfyear	= $month > 6 ? 1 : 0;
                    $quarter 	= $this->quarter($month);

                    $tdate		= date('Y-m-d', $r['eotime']);
                    $tyear		= date('Y', $r['eotime']);
                    $tmonth		= date('n', $r['eotime']);
                    $tweek		= date('W', $r['eotime']);
                    $tday		= date('j', $r['eotime']);
                    $thalfyear	= $tmonth > 6 ? 1 : 0;
                    $tquarter 	= $this->quarter($tmonth);

                    $update['eotime'] = $nowtime;
                    // 年
                    $update['eoyear'] = $tyear !== $year ? 0 : 'eoyear + 1';
                    // 半年
                    $update['eohalfyear'] = $thalfyear !== $halfyear ? 0 : 'eohalfyear + 1';
                    // 季度
                    $update['eoquarter'] = $tquarter !== $quarter ? 0 : 'eoquarter + 1';
                    // 月
                    $update['eomonth'] = $tmonth !== $month ? 0 : 'eomonth + 1';
                    // 周
                    $update['eoweek'] = $tyear !== $year || $tweek !== $week ? 0 : 'eoweek + 1';
                    // 天
                    $update['eoday'] = $tyear . '-' . $tmonth.'-'.$tday !== $year . '-' . $month . '-' . $day ? 0 : 'eoday + 1';
                    // 昨天
                    if($tdate !== $date) {

                        $update['eoyesterday'] = date('Y-m-d',$nowtime - 24 * 3600) == $tdate ? $r['eoday'] : 0;
                    }
                }
            }

            $this->update(['id' => $add['id']], $update);
        }
        elseif (1 === (int)$public_r['onclicktype']) {

            $tid = $class_r[$add['classid']]['tid'];
            $filename = ECMS_PATH . 'c' . DIRECTORY_SEPARATOR . 'ecachepub' . DIRECTORY_SEPARATOR . 'efilecache' . DIRECTORY_SEPARATOR . 'econclick' . DIRECTORY_SEPARATOR . 'ocinfo' . $tid . '.log';

            $this->addUpdate($add['id'], $filename);
            $this->doUpdate('id', 'onclick', $filename);
        }

        return [];
    }

    /**
     * 加入点击缓存
     *
     * @param int $id
     * @param string $filename
     * @return void
    */
    private function addUpdate(int $id, string $filename): void
    {
        if($fp = fopen($filename, 'ab')){

            fwrite($fp, "$id\n");
            fclose($fp);
        }
    }

    /**
     * 更新点击缓存
     *
     * @param int $id
     * @param string $filename
     * @return void
    */
    private function doUpdate(string $idf, string $onclickf, string $filename): string
    {
        global $public_r;

        if(file_exists($filename) && (filesize($filename) >= $public_r['onclickfilesize'] * 1024 || time() - filectime($filename) >= $public_r['onclickfiletime'] * 60)){
            $lr = $ocr = [];
            if($lr = file($filename)){

                if(!unlink($filename)){

                    if($fp = fopen($filename, 'wb')){

                        fwrite($fp, '');
                        fclose($fp);
                    }
                }
                $lr = array_count_values($lr);
                foreach($lr as $id => $oc){

                    if (!isset($ocr[$oc])) $ocr[$oc] = [];
                    array_push($ocr[$oc], intval($id));
                }

                foreach($ocr as $oc => $ids){

                    if (count($ids) > 1) {

                        $this->update([$idf . ' in' => $ids], [$onclickf => $onclickf . ' + ' . intval($oc)]);
                    }
                    else {

                        $this->update([$idf => $ids], [$onclickf => $onclickf . ' + ' . intval($oc)]);
                    }
                }
            }
        }

        return '';
    }

    /**
     * 季度
     *
     * @param int $manth
     * @return int
     */
    private function quarter(int $month): int
    {
        return match (true) {
            $month >= 4 && $month <= 6 => 2,
            $month >= 7 && $month <= 9 => 3,
            $month >= 10 && $month <= 12 => 4,
            default => 1,
        };
    }

    /**
     * 存在cookie
     *
     * @param string $cookieName
     * @param string $value
     * @return bool
     */
    private function checkCookie(string $cookieName, string $value): bool
    {
        $doupdate = true;
        $onclickrecord = getcvar($cookieName);
        if(str_contains($onclickrecord, ',' . $value . ',')) {
            $doupdate = false;
        }
        else {

            $newval = empty($onclickrecord) ? ',' . $value .',' : $onclickrecord . $value . ',';
            esetcookie($cookieName, $newval);
        }

        if(empty($_COOKIE))	$doupdate = false;

        return $doupdate;
    }
}
